package com.cqq.common.core.util;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * <h3>Set 构建类</h3>
 * 
 * <p>使用链式方式进行set的快速构建</p>
 * <pre class="code">SetBuilder.add(object1).and(object2).and(object3).build();</pre>
 * 
 * @author GUOQIANG
 * @version 1.0.0
 */
public class SetBuilder<T> {

	private Set<T> set;

	private SetBuilder() {
		set = newHashSet();
	}

	/**
	 * <h3>添加一个对象</h3>
	 * 
	 * @param <T> 对象类型
	 * @param value 需要加入set的对象
	 * @return SetBuilder
	 */
	public static <T> SetBuilder<T> add(T value) {
		SetBuilder<T> setBuilder = new SetBuilder<T>();
		if (value != null) {
			setBuilder = setBuilder.and(value);
		}
		return setBuilder;
	}

	/**
	 * <h3>添加多个对象</h3>
	 * 
	 * @param <T> 对象类型
	 * @param values 需要加入set的对象
	 * @return SetBuilder
	 */
	public static <T> SetBuilder<T> addAll(T[] values) {
		SetBuilder<T> setBuilder = new SetBuilder<T>();
		if (values != null) {
			for (T value : values) {
				setBuilder = setBuilder.and(value);
			}
		}
		return setBuilder;
	}

	/**
	 * <h3>添加一个对象</h3>
	 * 
	 * @param value 需要加入set的对象
	 * @return SetBuilder
	 */
	public SetBuilder<T> and(T value) {
		if (value != null) {
			set.add(value);
		}
		return this;
	}

	/**
	 * <h3>删除一个对象</h3>
	 * 
	 * @param value 需要删除set的对象
	 * @return SetBuilder
	 */
	public SetBuilder<T> del(T value) {
		if (value != null) {
			set.remove(value);
		}
		return this;
	}

	/**
	 * <h3>生成list对象</h3>
	 * 
	 * @return list
	 */
	public Set<T> build() {
		return set;
	}

	/**
	 * <h3>生成array对象</h3>
	 * 
	 * <p>如果set中没有元素返回null</p>
	 * 
	 * @return list
	 */
	@SuppressWarnings("unchecked")
	public T[] buildArray() {
		T[] arr = null;
		for (T obj : set) {
			if (obj != null) {
				arr = (T[]) Array.newInstance(obj.getClass(), set.size());
				arr = set.toArray(arr);
				break;
			}
		}
		return arr;
	}

	public static <K> Set<K> newHashSet() {
		return new HashSet<K>();
	}

	public static <K> Set<K> newHashSet(Collection<K> c) {
		return new HashSet<K>(c);
	}

	public static <K> Set<K> newHashSet(int size) {
		return new HashSet<K>(size);
	}
}